package com.rc.activity.provider;

import java.util.ArrayList;

import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteConstraintException;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;

import com.rc.activity.DashBoardScreen;
import com.rc.activity.R;
import com.rc.activity.dao.DaoMaster;
import com.rc.activity.dao.DaoMaster.DevOpenHelper;
import com.rc.activity.dao.DaoSession;
import com.rc.activity.dao.tbl_Category;
import com.rc.activity.dao.tbl_CategoryDao;
import com.rc.activity.dao.tbl_Count;
import com.rc.activity.dao.tbl_CountDao;
import com.rc.activity.dao.tbl_Item;
import com.rc.activity.dao.tbl_ItemDao;
import com.rc.activity.dao.tbl_Merchant;
import com.rc.activity.dao.tbl_MerchantDao;
import com.rc.activity.dao.tbl_Profile;
import com.rc.activity.dao.tbl_ProfileDao;
import com.rc.activity.dao.tbl_Receipt;
import com.rc.activity.dao.tbl_ReceiptDao;
import com.rc.activity.dao.tbl_Report;
import com.rc.activity.dao.tbl_ReportDao;
import com.rc.activity.dao.tbl_Settings;
import com.rc.activity.dao.tbl_SettingsDao;
import com.rc.activity.dao.tbl_Trip;
import com.rc.activity.dao.tbl_TripDao;
import com.rc.activity.dao.tbl_TripItems;
import com.rc.activity.dao.tbl_TripItemsDao;
import com.rc.activity.dao.tbl_User;
import com.rc.activity.dao.tbl_UserDao;
import com.rc.util.Const;

public class ContentProviderApp extends ContentProvider {
	public static final UriMatcher URI_MATCHER = buildUriMatcher();

	// Register PATH receipt
	public static final String PATH_RECEIPT_DELETE = "receipt";
	public static final int PATH_TOKEN_RECEIPT_DELETE = 99;

	public static final String PATH_RECEIPT = "receipt";
	public static final int PATH_TOKEN_RECEIPT = 100;

	// Register PATH user
	public static final String PATH_USER = "user";
	public static final int PATH_TOKEN_USER = 101;

	// Register PATH Merchant
	public static final String PATH_MERCHANT = "merchant";
	public static final int PATH_TOKEN_MERCHANT = 102;

	public static final String PATH_FOR_ID_MERCHANT = "merchant/*";
	public static final int PATH_FOR_ID_TOKEN_MERCHANT = 202;

	// Register PATH Count
	public static final String PATH_COUNT = "count";
	public static final int PATH_TOKEN_COUNT = 203;

	// Register PATH Report
	public static final String PATH_REPORT = "report";
	public static final int PATH_TOKEN_REPORT = 204;

	// Register PATH Report
	public static final String PATH_TRIP = "trip";
	public static final int PATH_TOKEN_TRIP = 205;

	// Register PATH Category
	public static final String PATH_CATEGORY = "Category";
	public static final int PATH_TOKEN_CATEGORY = 206;

	// Register PATH Items
	public static final String PATH_ITEMS = "Items";
	public static final int PATH_TOKEN_ITEMS = 207;

	// Register PATH Profile
	public static final String PATH_PROFILE = "Profile";
	public static final int PATH_TOKEN_PROFILE = 208;

	// Register PATH TripItems
	public static final String PATH_TRIP_ITEM = "TripItems";
	public static final int PATH_TOKEN_TRIP_ITEM = 209;

	// Register PATH Setting
	public static final String PATH_SETTING = "Settings";
	public static final int PATH_TOKEN_SETTING = 210;

	public static final String AUTHORITY = "com.rc.activity";

	// Uri Matcher for the content provider
	private static UriMatcher buildUriMatcher() {
		final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
		final String authority = Contract.AUTHORITY;

		// add Match Receipt
		matcher.addURI(authority, PATH_RECEIPT_DELETE,
				PATH_TOKEN_RECEIPT_DELETE);
		matcher.addURI(authority, PATH_RECEIPT, PATH_TOKEN_RECEIPT);

		// add Match User
		matcher.addURI(authority, PATH_USER, PATH_TOKEN_USER);

		// add Match Merchant
		matcher.addURI(authority, PATH_MERCHANT, PATH_TOKEN_MERCHANT);
		matcher.addURI(authority, PATH_FOR_ID_MERCHANT,
				PATH_FOR_ID_TOKEN_MERCHANT);

		// add Match Count
		matcher.addURI(authority, PATH_COUNT, PATH_TOKEN_COUNT);

		// add Match Report
		matcher.addURI(authority, PATH_REPORT, PATH_TOKEN_REPORT);

		// add Match Trip
		matcher.addURI(authority, PATH_TRIP, PATH_TOKEN_TRIP);

		// add Match Category
		matcher.addURI(authority, PATH_CATEGORY, PATH_TOKEN_CATEGORY);

		// add Match Items
		matcher.addURI(authority, PATH_ITEMS, PATH_TOKEN_ITEMS);

		// add Match Profile
		matcher.addURI(authority, PATH_PROFILE, PATH_TOKEN_PROFILE);

		// add Match Trip Items
		matcher.addURI(authority, PATH_TRIP_ITEM, PATH_TOKEN_TRIP_ITEM);

		// add Match Settings
		matcher.addURI(authority, PATH_SETTING, PATH_TOKEN_SETTING);

		return matcher;
	}

	public static SQLiteDatabase db;

	public static DaoSession daoSession;
	private Cursor cursor;
	private tbl_ReceiptDao daoReceipt;
	private tbl_MerchantDao daoMerchant;
	private tbl_CountDao daoCount;
	private tbl_CategoryDao daoCategory;
	private tbl_UserDao daoUser;
	private tbl_ReportDao daoReport;
	private tbl_TripDao daoTrip;
	private tbl_ItemDao daoItems;
	private tbl_ProfileDao daoProfile;
	private tbl_TripItemsDao daoTripItems;
	private tbl_SettingsDao daoSettings;

	@Override
	public boolean onCreate() {

		DevOpenHelper helper = new DaoMaster.DevOpenHelper(getContext(),
				Const.DATABASE_NAME, null);
		db = helper.getWritableDatabase();
		DaoMaster daoMaster = new DaoMaster(db);
		DaoMaster.createAllTables(db, true);
		daoSession = daoMaster.newSession();
		daoReceipt = daoSession.getTbl_ReceiptDao();
		daoMerchant = daoSession.getTbl_MerchantDao();
		daoCount = daoSession.getTbl_CountDao();
		daoUser = daoSession.getTbl_UserDao();
		tbl_UserDao.createTable(db, true);
		daoReport = daoSession.getTbl_ReportDao();
		daoTrip = daoSession.getTbl_TripDao();
		daoCategory = daoSession.getTbl_CategoryDao();
		daoItems = daoSession.getTbl_ItemDao();
		daoProfile = daoSession.getTbl_ProfileDao();
		daoTripItems = daoSession.getTbl_TripItemsDao();
		daoSettings = daoSession.getTbl_SettingsDao();
		return true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {

		final int match = URI_MATCHER.match(uri);
		switch (match) {
		case PATH_TOKEN_RECEIPT: {
			if (selection == null) {
				selection = tbl_ReceiptDao.Properties.IsDelete.columnName
						+ " = ''";
			} else {
				if (selection
						.indexOf(tbl_ReceiptDao.Properties.IsDelete.columnName) == -1) {
					selection = selection + " and "
							+ tbl_ReceiptDao.Properties.IsDelete.columnName
							+ " = ''";
				}

			}
			cursor = db.query(daoReceipt.getTablename(),
					daoReceipt.getAllColumns(), selection, selectionArgs, null,
					null, sortOrder);
			return cursor;
		}

		case PATH_TOKEN_PROFILE: {
			cursor = db.query(daoProfile.getTablename(),
					daoProfile.getAllColumns(), selection, selectionArgs, null,
					null, sortOrder);
			return cursor;
		}

		case PATH_TOKEN_SETTING: {
			cursor = db.query(daoSettings.getTablename(),
					daoSettings.getAllColumns(), selection, selectionArgs,
					null, null, sortOrder);
			return cursor;
		}

		case PATH_TOKEN_RECEIPT_DELETE: {
			cursor = db.query(daoReceipt.getTablename(),
					daoReceipt.getAllColumns(), selection, selectionArgs, null,
					null, sortOrder);
			return cursor;
		}
		case PATH_TOKEN_USER: {
			cursor = db.query(daoUser.getTablename(), daoUser.getAllColumns(),
					selection, selectionArgs, null, null, sortOrder);
			return cursor;
		}
		case PATH_TOKEN_COUNT: {
			cursor = db.query(daoCount.getTablename(),
					daoCount.getAllColumns(), selection, selectionArgs, null,
					null, sortOrder);
			return cursor;
		}
		case PATH_TOKEN_REPORT: {
			if (selection == null) {
				selection = tbl_ReceiptDao.Properties.IsDelete.columnName
						+ " = ''";
			} else {
				if (selection
						.indexOf(tbl_TripDao.Properties.IsDelete.columnName) == -1) {
					selection = selection + " and "
							+ tbl_ReceiptDao.Properties.IsDelete.columnName
							+ " = ''";
				}

			}
			cursor = db.query(daoReport.getTablename(),
					daoReport.getAllColumns(), selection, selectionArgs, null,
					null, sortOrder);
			return cursor;
		}
		case PATH_TOKEN_TRIP: {
			if (selection == null) {
				selection = tbl_ReceiptDao.Properties.IsDelete.columnName
						+ " = ''";
			} else {
				selection = selection + " and "
						+ tbl_ReceiptDao.Properties.IsDelete.columnName
						+ " = ''";
			}
			cursor = db.query(daoTrip.getTablename(), daoTrip.getAllColumns(),
					selection, selectionArgs, null, null, sortOrder);
			return cursor;
		}

		case PATH_TOKEN_TRIP_ITEM: {
			if (selection == null) {
				selection = tbl_ReceiptDao.Properties.IsDelete.columnName
						+ " = ''";
			} else {
				selection = selection + " and "
						+ tbl_ReceiptDao.Properties.IsDelete.columnName
						+ " = ''";
			}
			cursor = db.query(daoTripItems.getTablename(),
					daoTripItems.getAllColumns(), selection, selectionArgs,
					null, null, sortOrder);
			return cursor;
		}

		case PATH_TOKEN_MERCHANT: {
			cursor = db.query(daoMerchant.getTablename(),
					daoMerchant.getAllColumns(), selection, selectionArgs,
					null, null, sortOrder);
			return cursor;
		}
		case PATH_TOKEN_CATEGORY: {
			cursor = db.query(daoCategory.getTablename(),
					daoCategory.getAllColumns(), selection, selectionArgs,
					null, null, sortOrder);
			return cursor;
		}
		case PATH_TOKEN_ITEMS: {
			if (selection == null) {
				selection = tbl_ItemDao.Properties.IsDelete.columnName
						+ " = ''";
			} else {
				if (selection
						.indexOf(tbl_ItemDao.Properties.IsDelete.columnName) == -1) {
					selection = selection + " and "
							+ tbl_ItemDao.Properties.IsDelete.columnName
							+ " = ''";
				}

			}
			cursor = db.query(daoItems.getTablename(),
					daoItems.getAllColumns(), selection, selectionArgs, null,
					null, sortOrder);
			return cursor;
		}

		default:
			return null;
		}

	}

	@Override
	public String getType(Uri uri) {
		final int match = URI_MATCHER.match(uri);
		Log.e("123", uri.toString());
		switch (match) {
		case PATH_TOKEN_RECEIPT:
			return Contract.CONTENT_TYPE_DIR;
		default:
			throw new UnsupportedOperationException("URI " + uri
					+ " is not supported.");
		}
	}

	@Override
	public int bulkInsert(Uri uri, ContentValues[] values) {
		// TODO Auto-generated method stub
		int uriType = 0;
		int insertCount = 0;
		try {
			uriType = URI_MATCHER.match(uri);
			switch (uriType) {
			// case MEASUREMENTS:
			// try {
			// sqlDB.beginTransaction();
			// for (ContentValues value : values) {
			// long id = sqlDB.insert(Tab_Measurements.TABLE_NAME,
			// null, value);
			// if (id > 0)
			// insertCount++;
			// }
			// sqlDB.setTransactionSuccessful();
			// } catch (Exception e) {
			// // Your error handling
			// } finally {
			// sqlDB.endTransaction();
			// }
			// break;
			default:
				throw new IllegalArgumentException("Unknown URI: " + uri);
			}
			// getContext().getContentResolver().notifyChange(uri, null);
		} catch (Exception e) {
			// Your error handling
		}

		return insertCount;
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		int token = URI_MATCHER.match(uri);
		// insert to data base return id
		long id = 0;// get when insert success.
		switch (token) {
		case PATH_TOKEN_RECEIPT: {
			try {
				id = daoReceipt.insert(tbl_Receipt
						.getObjectByContentValues(values));
			} catch (SQLiteConstraintException e) {
				// TODO: handle exception
				e.printStackTrace();
				id = -1;
			}
			Log.e("Receipt id", id + "");
			if (id != -1)
				getContext().getContentResolver().notifyChange(uri, null);
			return Contract.CONTENT_URI_RECEIPT.buildUpon()
					.appendPath(String.valueOf(id)).build();
		}

		case PATH_TOKEN_SETTING: {
			try {
				id = daoSettings.insert(tbl_Settings
						.getObjectByContentValues(values));
			} catch (SQLiteConstraintException e) {
				// TODO: handle exception
				e.printStackTrace();
				id = -1;
			}
			Log.e("setting id", id + "");
			if (id != -1)
				getContext().getContentResolver().notifyChange(uri, null);
			return Contract.CONTENT_URI_SETTING.buildUpon()
					.appendPath(String.valueOf(id)).build();
		}

		case PATH_TOKEN_PROFILE: {
			try {
				id = daoProfile.insert(tbl_Profile
						.getObjectByContentValues(values));
			} catch (SQLiteConstraintException e) {
				// TODO: handle exception
				e.printStackTrace();
				id = -1;
			}
			if (id != -1)
				getContext().getContentResolver().notifyChange(uri, null);
			Log.e("Profile id", id + "");
			return Contract.CONTENT_URI_PROFILE.buildUpon()
					.appendPath(String.valueOf(id)).build();
		}
		case PATH_TOKEN_MERCHANT: {
			// insert to data base return id
			id = daoMerchant.insert(tbl_Merchant.setContentValues(values));
			if (id != -1)
				getContext().getContentResolver().notifyChange(uri, null);
			return Contract.CONTENT_URI_MERCHANT.buildUpon()
					.appendPath(String.valueOf(id)).build();
		}

		case PATH_TOKEN_REPORT: {
			try {
				id = daoReport.insert(tbl_Report.setContentValues(values));
			} catch (SQLiteConstraintException e) {
				// TODO: handle exception
				e.printStackTrace();
				id = -1;
			}
			Log.e("Report id", id + "");
			if (id != -1)
				getContext().getContentResolver().notifyChange(uri, null);
			return Contract.CONTENT_URI_REPORT.buildUpon()
					.appendPath(String.valueOf(id)).build();
		}

		case PATH_TOKEN_TRIP: {
			try {
				id = daoTrip.insert(tbl_Trip.setContentValues(values));
			} catch (SQLiteConstraintException e) {
				// TODO: handle exception
				e.printStackTrace();
				id = -1;
			}
			Log.e("Trip id", id + "");
			if (id != -1)
				getContext().getContentResolver().notifyChange(uri, null);
			return Contract.CONTENT_URI_TRIP.buildUpon()
					.appendPath(String.valueOf(id)).build();
		}

		case PATH_TOKEN_USER: {
			try {
				id = daoUser.insert(tbl_User.setContentValues(values));
			} catch (SQLiteConstraintException e) {
				// TODO: handle exception
				e.printStackTrace();
				id = -1;
			}
			if (id != -1)
				getContext().getContentResolver().notifyChange(uri, null);
			return Contract.CONTENT_URI_USER.buildUpon()
					.appendPath(String.valueOf(id)).build();
		}

		case PATH_TOKEN_TRIP_ITEM: {
			try {

				cursor = db.query(daoTripItems.getTablename(),
						daoTripItems.getAllColumns(),
						tbl_TripItemsDao.Properties.TripItemID.columnName
								+ " = "
								+ tbl_TripItems.setContentValues(values)
										.getTripItemID(), null, null, null,
						null);
				if (cursor.getCount() == 0) {
					id = daoTripItems.insert(tbl_TripItems
							.setContentValues(values));
				}

			} catch (SQLiteConstraintException e) {
				// TODO: handle exception
				e.printStackTrace();
				id = -1;
			}
			if (id != -1)
				getContext().getContentResolver().notifyChange(uri, null);
			Log.e("Item Trip - ID", id + "");
			return Contract.CONTENT_URI_TRIP_ITEM.buildUpon()
					.appendPath(String.valueOf(id)).build();
		}

		case PATH_TOKEN_COUNT: {
			try {
				id = daoCount.insert(tbl_Count.setContentValues(values));
			} catch (SQLiteConstraintException e) {
				// TODO: handle exception
				e.printStackTrace();
				id = -1;
			}
			if (id != -1)
				getContext().getContentResolver().notifyChange(uri, null);
			return Contract.CONTENT_URI_COUNT.buildUpon()
					.appendPath(String.valueOf(id)).build();
		}
		case PATH_TOKEN_CATEGORY: {
			try {
				id = daoCategory.insert(tbl_Category.setContentValues(values));
			} catch (SQLiteConstraintException e) {
				// TODO: handle exception
				e.printStackTrace();
				id = -1;
			}
			Log.e("Category id", id + "");
			if (id != -1)
				getContext().getContentResolver().notifyChange(uri, null);
			return Contract.CONTENT_URI_CATEGORY.buildUpon()
					.appendPath(String.valueOf(id)).build();
		}

		case PATH_TOKEN_ITEMS: {
			try {
				id = daoItems.insert(tbl_Item.setContentValues(values));
				Log.e("Item - ID", id + "");
			} catch (SQLiteConstraintException e) {
				// TODO: handle exception
				e.printStackTrace();
				id = -1;

			}
			if (id != -1) {
				getContext().getContentResolver().notifyChange(uri, null);
				ContentResolver.requestSync(DashBoardScreen.mConnectedAccount,
						Contract.AUTHORITY, new Bundle());
			}
			return Contract.CONTENT_URI_ITEMS.buildUpon()
					.appendPath(String.valueOf(id)).build();
		}
		default: {
			throw new UnsupportedOperationException("URI: " + uri
					+ " not supported.");
		}
		}

	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		int token = URI_MATCHER.match(uri);
		int rowsDeleted = -1;
		switch (token) {
		case (PATH_TOKEN_RECEIPT):
			// delete receipt
			rowsDeleted = db.delete(tbl_ReceiptDao.TABLENAME, selection,
					selectionArgs);
			break;
		case PATH_TOKEN_MERCHANT:
			rowsDeleted = db.delete(tbl_MerchantDao.TABLENAME, selection,
					selectionArgs);
			break;
		case PATH_TOKEN_TRIP:
			rowsDeleted = db.delete(tbl_TripDao.TABLENAME, selection,
					selectionArgs);
			break;
		case PATH_TOKEN_ITEMS:
			rowsDeleted = db.delete(tbl_ItemDao.TABLENAME, selection,
					selectionArgs);
			break;
		case PATH_TOKEN_REPORT:
			rowsDeleted = db.delete(tbl_ReportDao.TABLENAME, selection,
					selectionArgs);
			break;
		case PATH_TOKEN_TRIP_ITEM:
			rowsDeleted = db.delete(tbl_TripItemsDao.TABLENAME, selection,
					selectionArgs);
			break;
		default:
			throw new IllegalArgumentException("Unsupported URI: " + uri);
		}
		// Notifying the changes, if there are any
		if (rowsDeleted != -1)
			getContext().getContentResolver().notifyChange(uri, null, true);
		return rowsDeleted;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		int token = URI_MATCHER.match(uri);
		int rowsDeleted = -1;
		switch (token) {
		case PATH_TOKEN_RECEIPT:
			rowsDeleted = db.update(tbl_ReceiptDao.TABLENAME, values,
					selection, selectionArgs);
			Log.e("update receipt", rowsDeleted + "");
			break;
		case PATH_TOKEN_MERCHANT:
			rowsDeleted = db.update(tbl_MerchantDao.TABLENAME, values,
					selection, selectionArgs);
			Log.e("update merchant", rowsDeleted + "");
			break;
		case PATH_TOKEN_REPORT:
			rowsDeleted = db.update(tbl_ReportDao.TABLENAME, values, selection,
					selectionArgs);
			Log.e("update report", rowsDeleted + "");
			break;
		case PATH_TOKEN_ITEMS:
			rowsDeleted = db.update(tbl_ItemDao.TABLENAME, values, selection,
					selectionArgs);
			Log.e("update items", rowsDeleted + "");
			break;

		case PATH_TOKEN_TRIP_ITEM:
			rowsDeleted = db.update(tbl_TripItemsDao.TABLENAME, values,
					selection, selectionArgs);
			Log.e("update trip item", rowsDeleted + "");
			break;
		case PATH_TOKEN_PROFILE:
			rowsDeleted = db.update(tbl_ProfileDao.TABLENAME, values,
					selection, selectionArgs);
			Log.e("update profile", rowsDeleted + "");
			break;
		case PATH_TOKEN_TRIP:
			rowsDeleted = db.update(tbl_TripDao.TABLENAME, values, selection,
					selectionArgs);
			Log.e("update trip", rowsDeleted + "");
			break;
		case PATH_TOKEN_SETTING:
			rowsDeleted = db.update(tbl_SettingsDao.TABLENAME, values,
					selection, selectionArgs);
			break;
		case PATH_TOKEN_USER:
			rowsDeleted = db.update(tbl_UserDao.TABLENAME, values, selection,
					selectionArgs);
			break;
		default:
			throw new IllegalArgumentException("Unsupported URI: " + uri);
		}
		// Notifying the changes, if there are any
		if (rowsDeleted != -1) {
			getContext().getContentResolver().notifyChange(uri, null);
			ContentResolver.requestSync(DashBoardScreen.mConnectedAccount,
					Contract.AUTHORITY, new Bundle());
		}
		return rowsDeleted;
	}

	public static boolean checkReceiptByTripID(Context ct, long tripID) {
		Cursor cursor = ct.getContentResolver().query(
				Contract.CONTENT_URI_TRIP,
				null,
				tbl_TripDao.Properties.TripID.columnName + " = '" + tripID
						+ "'", null, null);
		ArrayList<tbl_Trip> arrTrip = new ArrayList<tbl_Trip>();
		arrTrip = tbl_Trip.getObjectbyCursor(cursor);
		for (tbl_Trip objTrip : arrTrip) {
			long reportID = objTrip.getReport_ID();
			CheckDeleteReport(ct, reportID);
		}
		return true;
	}

	/**
	 * Rule : chỉ cho phép xóa report thuộc draft reports và reject
	 * report
	 */
	public static boolean CheckDeleteReport(Context ct, long mReportID) {

		Cursor cursor = ct.getContentResolver().query(
				Contract.CONTENT_URI_REPORT,
				null,
				tbl_ReportDao.Properties.ReportID.columnName + " = '"
						+ mReportID + "'", null, null);
		ArrayList<tbl_Report> arrReport = new ArrayList<tbl_Report>();
		arrReport = tbl_Report.getObjectbyCursor(cursor);
		for (tbl_Report objReport : arrReport) {
			if (!ct.getString(R.string.draft_reports).equals(
					objReport.getReportType())
					|| !ct.getString(R.string.rejected_reports).equals(
							objReport.getReportType())) {
				return false;
			}
		}
		return true;
	}

}
